/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#include "simodo/interpret/builtins/hosts/base/BaseOperationParser.h"
#include "simodo/interpret/builtins/hosts/base/BaseInterpret_abstract.h"
#include "simodo/bormental/DrBormental.h"

namespace simodo::interpret::builtins
{

InterpretState BaseOperationParser::parseNone(BaseInterpret_abstract &host, const ast::Node & )
{
    // node(None, )

    return host.executeNone();
}

InterpretState BaseOperationParser::parsePushConstant(BaseInterpret_abstract &host, const ast::Node & op)
{
    // node(PushConstant, constant_value)

    return host.executePushConstant(op.token());
}

InterpretState BaseOperationParser::parsePushVariable(BaseInterpret_abstract &host, const ast::Node & op)
{
    // node(PushVariable, variable_name)

    return host.executePushValue(op.token());
}

InterpretState BaseOperationParser::parseObjectElement(BaseInterpret_abstract &host, const ast::Node & op)
{
    // node(ObjectElement, dot)
    //    |
    //    ---- node(, variable_name) * 1..1

    if (op.branches().empty())
        throw bormental::DrBormental("BaseOperationParser::parseObjectElement", "The structure of the semantic tree is broken");

    return host.executeObjectElement(op.token(), op.branches().front().token());
}

InterpretState BaseOperationParser::parseFunctionCall(BaseInterpret_abstract &host, const ast::Node & op)
{
    // node(FunctionCall, parenthesis)
    //    |
    //    ---- node() * 0..n (список выражений)

    return host.executeFunctionCall(op);
}

InterpretState BaseOperationParser::parseProcedureCheck(BaseInterpret_abstract &host, const ast::Node & )
{
    // node(ProcedureCheck, )

    // Предполагается, что оператор ProcedureCheck выполняется сразу после вызова функции/процедуры

    return host.executeProcedureCheck();
}

InterpretState BaseOperationParser::parseBlock(BaseInterpret_abstract &host, const ast::Node & op)
{
    // node(Block, isBeginningOfBlock)

    return host.executeBlock(op);
}

InterpretState BaseOperationParser::parsePop(BaseInterpret_abstract &host, const ast::Node & )
{
    // node(Pop, )

    return host.executePop();
}

}